﻿Shader "Ly/Liquid"
{
	Properties
	{
		_Tint("Tint", Color) = (1,1,1,1)
		_MainTex("Texture", 2D) = "white" {}
    	_FillAmount("Fill Amount", Range(-10,10)) = 0.0
		[HideInInspector] _WobbleX("WobbleX", Range(-1,1)) = 0.0
		[HideInInspector] _WobbleZ("WobbleZ", Range(-1,1)) = 0.0
		_TopColor("Top Color", Color) = (1,1,1,1)
		_FoamColor("Foam Line Color", Color) = (1,1,1,1)
		_Rim("Foam Line Width", Range(0,0.1)) = 0.0
		_RimColor("Rim Color", Color) = (1,1,1,1)
		_RimPower("Rim Power", Range(0,10)) = 0.0

		_ThickCol("ThickCol", Color) = (1,0,0,1)
		_ThickFactor("ThickFactor", Range(0,1)) = 0.1
		
		_EdgePower("Edge Power", Range(0,1)) = 0.0
		_EdgeRimColor("EdgeRimColor", Color) = (1, 1, 1, 1)
		_EdgeRimIntensity("Edge Power", Range(0,1)) = 0.0

	}

		SubShader
	{
		Tags{ "Queue" = "Geometry" }


		Pass
		{
			Cull off // 双面渲染
			AlphaToMask On  // 设置透明度

			CGPROGRAM
#include "UnityCG.cginc"  
		float4 _ThickCol;
		float _ThickFactor;
		float _EdgePower;
		float _EdgeRimIntensity;

		float4 _EdgeRimColor;
		struct v2f
		{
			float4 pos : SV_POSITION;
			float3 normal : COLOR0;
			float3 viewDir : COLOR1;
		};

		v2f vert(appdata_full v)
		{
			v2f o;
			o.pos = UnityObjectToClipPos(v.vertex); 
			float3 mvnormal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);
			float2 thickness = TransformViewToProjection(mvnormal.xy);
			o.pos.xy += thickness * _ThickFactor;
			o.normal = v.normal;
			o.viewDir = normalize(ObjSpaceViewDir(v.vertex));
			return o;
		}

		fixed4 frag(v2f i) : SV_Target
		{
			float dotProduct = 1 - pow(dot(i.normal, i.viewDir), _EdgePower);
		    float4 RimResult = smoothstep(0.5, 1.0, dotProduct) * _EdgeRimColor * _EdgeRimIntensity;
			float col = _ThickCol + RimResult;
		  
			return col;
		}

			//使用vert函数和frag函数  
#pragma vertex vert  
#pragma fragment frag  
			ENDCG
		}


		Pass
	{
		Zwrite On
		Cull Off 
		AlphaToMask On 

		CGPROGRAM


#pragma vertex vert
#pragma fragment frag
		// make fog work
#pragma multi_compile_fog

#include "UnityCG.cginc"

		struct appdata
	{
		float4 vertex : POSITION;
		float2 uv : TEXCOORD0;
		float3 normal : NORMAL;
	};

	struct v2f
	{
		float2 uv : TEXCOORD0;
		UNITY_FOG_COORDS(1)
			float4 vertex : SV_POSITION;
		float3 viewDir : COLOR;
		float3 normal : COLOR2;
		float fillEdge : TEXCOORD2;
	};

	sampler2D _MainTex;
	float4 _MainTex_ST;
	float _FillAmount, _WobbleX, _WobbleZ;
	float4 _TopColor, _RimColor, _FoamColor, _Tint;
	float _Rim, _RimPower;

	float4 RotateAroundYInDegrees(float4 vertex, float degrees)
	{
		float alpha = degrees * UNITY_PI / 180;
		float sina, cosa;
		sincos(alpha, sina, cosa);
		float2x2 m = float2x2(cosa, sina, -sina, cosa);
		return float4(vertex.yz , mul(m, vertex.xz)).xzyw;
	}


	v2f vert(appdata v)
	{
		v2f o;

		o.vertex = UnityObjectToClipPos(v.vertex);
		o.uv = TRANSFORM_TEX(v.uv, _MainTex);
		UNITY_TRANSFER_FOG(o,o.vertex);
		// get world position of the vertex
		float3 worldPos = mul(unity_ObjectToWorld, v.vertex.xyz);
		// rotate it around XY
		float3 worldPosX = RotateAroundYInDegrees(float4(worldPos,0),360);
		// rotate around XZ
		float3 worldPosZ = float3 (worldPosX.y, worldPosX.z, worldPosX.x);
		// combine rotations with worldPos, based on sine wave from script
		float3 worldPosAdjusted = worldPos + (worldPosX  * _WobbleX) + (worldPosZ* _WobbleZ);
		// how high up the liquid is
		o.fillEdge = worldPosAdjusted.y + _FillAmount;

		o.viewDir = normalize(ObjSpaceViewDir(v.vertex));
		o.normal = v.normal;
		return o;
	}

	fixed4 frag(v2f i, fixed facing : VFACE) : SV_Target
	{
		// sample the texture
		fixed4 col = tex2D(_MainTex, i.uv) * _Tint;
	// apply fog
	UNITY_APPLY_FOG(i.fogCoord, col);

	// rim light
	float dotProduct = 1 - pow(dot(i.normal, i.viewDir), _RimPower);
	float4 RimResult = smoothstep(0.5, 1.0, dotProduct);
	RimResult *= _RimColor;

	// foam edge
	float4 foam = (step(i.fillEdge, 0.5) - step(i.fillEdge, (0.5 - _Rim)));
	float4 foamColored = foam * (_FoamColor * 0.9);
	// rest of the liquid
	float4 result = step(i.fillEdge, 0.5) - foam;
	float4 resultColored = result * col;
	// both together, with the texture
	float4 finalResult = resultColored + foamColored;
	finalResult.rgb += RimResult;

	// color of backfaces/ top
	float4 topColor = _TopColor * (foam + result);
	//VFACE returns positive for front facing, negative for backfacing
	return facing > 0 ? finalResult : topColor;

	}
		ENDCG
	}

	}
}